<!DOCTYPE html>
<html lang='zh-Hans'>

<head>
    <meta charset='UTF-8'>
    <meta name='viewport' content='width=device-width, initial-scale=1.0'>
    <base href=''>
    <!--<script src='/lab/resources/eruda.js'></script>
    <script>eruda.init()</script>-->
    <title>web3</title>
    <link rel='stylesheet' href='/lab/resources/bootstrap/bootstrap.min.css'>
    <link rel='stylesheet' href='//at.alicdn.com/t/font_2905874_i762j9fqm1l.css'>
</head>

<body>
    <div class='container' id='root'>
        <h4 class='d-flex justify-content-center'>{{title}}</h4>
        <div class="row">
            <div class="col-12 d-flex justify-content-center pb-3">
                <button class="btn btn-primary btn-sm" @click="provider" :disabled="connectWalletStatus">
                    {{connectWalletStatus ? 'Connected!' : 'ConnectWallet'}}
                </button>
            </div>
            <div class="col-12 col-sm-8">
                <div class="input-group">
                    <input class="form-control" v-model="providerUrl">
                    <button class="btn btn-secondary">SetProvider</button>
                </div>
            </div>
            
            <div class="col-12">
                <ul class="list-group">
                    <template v-for="address of contractAddress">
                        <li class="list-group-item" :key="address">
                            <b>Contract</b><code>{{address}}</code>
                        </li>
                    </template>
                    
                    <li class="list-group-item">
                        <div class="input-group">
                            <input type="text" class="form-control" v-model="signContent">
                            <button class="btn btn-primary" @click="doSign">Sign</button>
                        </div>
                        <div class="col-12 flex justify-content-center text-break p-2">
                            {{signedContent}}
                        </div>
                    </li>
                </ul>
            </div>
        </div>
        <div class="row">
            <div class="col-12 col-sm-6">
                <div class="card">
                    <div class="card-body">
                        <h5 class="card-title">转账</h5>
                        <div class="pt-1 pb-4">
                            <div class="d-flex justify-content-around pb-1">
                                <span class="iconfont icon-ethereum">{{Math.round(this.etherAmount * 100) / 100}}</span>
                                <span class="iconfont icon-coin1">{{this.helloAmount}}</span>
                            </div>
                            <div class="input-group">
                                <span class="input-group-text iconfont icon-ethereum w-25">地址</span>
                                <input type="text" class="form-control" v-model="transferAcct" placeholder="Input Acct Addr">
                            </div>
                            <div class="input-group">
                                <span class="input-group-text iconfont icon-ethereum w-25">数量</span>
                                <input type="number" class="form-control" v-model="transferNum" placeholder="Input Acct Num">
                                <span class="input-group-text">ether</span>
                            </div>
                        </div>
                    </div>
                    <div class="card-footer d-flex justify-content-end">
                        <button class="btn btn-outline-primary btn-sm" @click="doTransfer">OK</button>
                    </div>
                </div>
            </div>
            <div class="col-12 col-sm-6">
                <div class="card">
                    <div class="card-body">
                        <h5 class="card-title">合约生成</h5>
                        <textarea rows="5" class="form-control" v-model="contractcode"
                            placeholder="please input contract code."
                        ></textarea>
                        <div class="pt-4 d-flex justify-content-end">
                            <button @click="generateContract" class="btn btn-outline-primary btn-sm">Generate</button>
                        </div>
                    </div>
                </div>
            </div>
            <div class="col-12">
                <div class="card">
                    <div class="card-body">
                        <h5 class="card-title">合约交互</h5>
                        <div class="input-group">
                            <span class="input-group-text"><span class="iconfont icon-contract2"></span></span>
                            <input type="text" v-model="contractAddress[0]" class="form-control">
                            <!-- <select class="form-select" v-model="selectedContractAddressIndex">
                                <option v-for="(address, index) in contractAddress" :key="address" :value="index">{{address}}</option>
                            </select> -->
                            <button class="btn btn-outline-primary" @click="executeContractInteract">DO</button>
                        </div>
                        <div class="input-group">
                            <span class="input-group-text"><span class="iconfont icon-ethereum"></span></span>
                            <input type="text" text="text" v-model="operationAddress" class="form-control">
                        </div>
                        <h6 class="text-center">合约信息</h6>
                        <div class="list-group">
                            <div class="list-group-item" v-for="(value, key) of contractDisplay" :key="key">
                                {{key}}: {{value}}
                            </div>
                        </div>
                        <div class="pt-4 d-flex justify-content-between">
                            <button class="btn btn-outline-primary btn-sm" @click="queryHelloBalance">query</button>
                            <button class="btn btn-outline-primary btn-sm" @click="minterHello">mine</button>
                        </div>mine
                    </div>
                </div>
            </div>
        </div>

    </div>
    <script src='/lab/resources/bootstrap/jquery.slim.min.js'></script>
    <script src='/lab/resources/bootstrap/bootstrap.bundle.min.js'></script>
    <script src='/lab/resources/vue.js'></script>
    <script src="lib/web3.min.js"></script>
    <script src="../dist/main.bundle.js"></script>
    <script>
        const {GetInfo} = window.st_web3lab
        const Web3 = window.Web3
        let w3 = null
        const app = new Vue({
            el: '#root',
            data: {
                title: 'web3',
                connectWalletStatus: false,
                addressList: [],
                providerUrl: 'http://localhost:7545/',
                signContent: 'for free',
                signedContent: "",
                transferAcct: "0x92297eB1857F3e8A5F804D0A1E03e6020Fd5A530",
                transferNum: "",
                contractcode: "",
                contractAddress: ["0xeDB85DbB4D9bcd74eaAE30D1D9Cc71e560f29Bb7", "0x1Bfb1b551B115EBCF79fEbd70ABD95e0fD27E91e-hello[modified]", "0x96941fE29A329EC07a006f224264aBAcC53E649f-hello[correct]"],
                contractAbi: [
                    JSON.parse('[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Sent","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balances","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"minter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"send","outputs":[],"stateMutability":"nonpayable","type":"function"}]'),
                ],
                contractDisplay: {"title": "for test"},
                selectedContractAddressIndex: 0,
                operationAddress: '0x92297eB1857F3e8A5F804D0A1E03e6020Fd5A530',
                etherAmount: 0,
                helloAmount: 0,
            },
            methods: {
                provider() {
                    if (Web3.givenProvider) {
                        console.log("env has provider")
                        w3 = new Web3(Web3.givenProvider)
                        w3.currentProvider.enable().then(v => {
                            console.log("connected!", v)
                            this.connectWalletStatus = true
                            this.addressList = v
                            GetInfo(w3).then(info => {
                                console.log("INFO:", info)
                            })
                            this.queryEtherBalance().then(v => {
                                this.etherAmount = v
                            })
                        }).catch(e => {
                            console.error("connect err:", e)
                        })
                    }
                },
                doSign() {
                    try {
                        if (this.signContent && this.addressList.length) {
                            console.log("prepare sign:", this.signContent)
                            w3.eth.personal.sign(this.signContent, this.addressList[0], "12345")
                                .then(signResult => {
                                    console.log("sign result:", signResult)
                                    this.signedContent = signResult
                                })
                                .catch(e => {
                                    console.error("sign err:", e)
                                })
                        } else {
                            alert("Please set provider firstly.")
                        }
                    } catch (e) {
                        console.error("sign exception:", e)
                    }
                },
                async doTransfer() {
                    amount = this.transferNum
                    account = this.transferAcct
                    if (!account || !account.trim() || !amount) {
                        alert("Please input amount and account")
                        return
                    }
                    if (!Web3.utils.isAddress(account)) {
                        alert("address invalid!")
                        return
                    }
                    let tx = {
                        from: this.addressList[0],
                        to: account,
                        gas: "21000",
                        // gasPrice: "20000000000",
                        value: Web3.utils.toWei(String(amount), "ether")
                    }
                    // let signedTx = await w3.eth.personal.signTransaction(tx)
                    // let transHash = await w3.eth.sendSignedTransaction(signedTx.raw)
                    let transHash = await w3.eth.sendTransaction(tx)
                    console.log("TranHash:", transHash)
                },
                async generateContract() {
                    if (!this.contractcode && !this.contractcode.trim()) {
                        alert("Please input contract code!")
                        return;
                    }
                    try {
                        let tx = {
                            from: this.addressList[0],
                            gas: "4200000",
                            data: "0x" + this.contractcode,
                        }
                        console.log("gen contract, tx:", tx)
                        let contract = await w3.eth.sendTransaction(tx)
                        console.log('gen contract:', contract)
                    } catch (e) {
                        console.error("genenrate contract err:", e)
                        if (e.stack) {
                            
                            console.error("[e.stack]:\n", e.stack)
                        }
                    }
                    // this.helloAmount = await this.queryHelloBalanceByAddress()
                },
                async executeContractInteract() {
                    if (this.contractObj) {
                        return;
                    }
                    contractAddr = this.contractAddress[0]
                    contractAbi = this.contractAbi[this.contractAddress.indexOf(contractAddr)]
                    // alert("begin interact with contract:")
                    const contract = new w3.eth.Contract(contractAbi, contractAddr)
                    this.contractObj = contract;
                    console.log('contract:', contract)
                    let minter = await contract.methods.minter().call()
                    console.log("minter:", minter)
                    let methods = Object.keys(contract.methods);
                    this.contractDisplay = {
                        methods: methods,
                        minter: minter,
                    }

                    let currentHelloAmount = await this.queryHelloBalanceByAddress()
                    this.helloAmount = currentHelloAmount;
                },
                async minterHello() {
                    if (!this.contractObj) {
                        alert("Please gain contract firstly")
                        return;
                    }
                    try {
                        let mineFunc = await this.contractObj.methods.mint(this.addressList[0], 100000000000000);
                        let tranResult = await mineFunc.send({
                            from: this.addressList[0],
                        })
                        console.log("tranResult:", tranResult)
                    } catch (e) {
                        console.error(e)
                    }
                },
                async queryHelloBalance() {
                    if (!this.contractObj) {
                        alert("Please gain contract firstly")
                        return;
                    }
                    let queryAddress = this.operationAddress;
                    let amount = await this.queryHelloBalanceByAddress(queryAddress)
                    alert("Account has " + amount + " hello token!")
                },
                async queryHelloBalanceByAddress(queryAddress) {
                    if (!queryAddress) {
                        queryAddress = this.addressList[0];
                    }
                    let balancesFunc = await this.contractObj.methods.balances(queryAddress);
                    let amount = await balancesFunc.call()
                    return amount
                },
                async queryEtherBalance(queryAddress) {
                    let wei = await w3.eth.getBalance(queryAddress ? queryAddress : this.addressList[0])
                    // console.log('wei:', wei)
                    return Web3.utils.fromWei(wei, 'ether')
                }

            },
        })
    </script>
</body>

</html>